using Localization.Resources.AbpUi;

using Microsoft.Extensions.DependencyInjection;

using Volo.Abp.ApiVersioning;
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.AutoMapper;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.FluentValidation;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using Volo.Abp.Validation.Localization;
using Volo.Abp.VirtualFileSystem;

using WL.Think.Abp.Localization;
using WL.Think.Abp.Modules;

namespace WL.Think.Abp
{
    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpLocalizationModule),
        typeof(AbpAutoMapperModule),
        typeof(AbpSwashbuckleModule),
        typeof(AbpApiVersioningAbstractionsModule),
        typeof(AbpAspNetCoreMvcUiThemeSharedModule),
        typeof(AbpAspNetCoreMultiTenancyModule),
        typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
        typeof(AbpAspNetCoreSerilogModule),
        typeof(AbpEntityFrameworkCoreModule),
        typeof(AbpFluentValidationModule)
    )]
    public class ThinkAbpCoreModule : ThinkModule<ThinkAbpCoreModule>
    {
        protected override void ConfigureLocalization(ServiceConfigurationContext context)
        {
            context.Services.Configure<AbpLocalizationOptions>(opts =>
            {
                opts.Resources.Add<ThinkResource>().AddBaseTypes(typeof(AbpValidationResource)).AddVirtualJson("/Localization/I18n");
                opts.Resources.Get<ThinkResource>().AddBaseTypes(typeof(AbpUiResource));

                opts.DefaultResourceType = typeof(ThinkResource);
                opts.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
                opts.Languages.Add(new LanguageInfo("en", "en", "English"));

                /**
                 ## 本地化配置注意点

                 1. 配置本地化的项目一定要依赖 AbpLocalizationModule 模块
                 2. 必须把给当前项目配置虚拟文件系统，并且必须的内嵌资源方式，因为本地化会去扫描配置的资源路径的json文件
                 3. 资源路径不能相同，如果相同，后面配置的会覆盖前面配置的，导致部分本地化显示异常
                    例如: 以本模块配置为例，这里配置的本地化资源路径是: /Localization/I18n。
                          那么后续配置本地化，不管是继承该本地化资源类 ThinkResource，还是为该本地化资源类添加额外的资源路径都不能是 /Localization/I18n。
                          否则当前配置的资源路径会被覆盖，导致里面配置属性无效
                 4. 本地化配置内嵌资源，必须一定要在当前项目中直接引入 Microsoft.Extensions.FileProviders.Embedded 包，
                    并且设置当前资源路径为 “不复制，嵌入的资源”，否则无法扫描该本地资源的文件生成内嵌资源。
                    可以直接编辑你的 .csproj 文件这样配置
                    <ItemGroup>
                       <EmbeddedResource Include = "MyResources\**\*.json"/>
                       <Content Remove = "MyResources\**\*.json"/>
                    </ItemGroup>
                 5. 配置的路径必须是当以当前项目为根路径，例如下面配置: 就是 WL.Think.Abp.Core 这个项目为根(/),然后加上文件夹的路径
                    opts.Resources.Add<ThinkResource>()
                          .AddBaseTypes(typeof(AbpValidationResource))
                          .AddVirtualJson("/Localization/I18n");
                 
                 
                 ## 通过扩展本地化资源，可以覆盖已有资源中的字段
                 
                 当第三方的本地化信息无法满足或者想要修改时，可以通过给第三方本地化资源类添加额外的资源文件路径，
                 这样就可以覆盖第三方资源中的字段.
                 
                 例如：
                 1. 登录用户页面中使用了 Account Abp 服务，并且其所有本地化资源都跟AccountResource绑定，
                 2. 当时我们想要修改登录用户页面中用户名的显示名称，把原有的 用户名或电子邮箱 改为 用户名或工号。
                 3. 这个时候就可以扩展 AccountResource 资源，并在资源文件中添加跟AccountResource相同的键，然后修改其值。
                    修改项如下："UserNameOrEmailAddress": "用户名或工号"
                 4. jsonPath 必须是在当前项目下的路径，而且必须保证不能跟原来的路径相同名称，否则会覆盖原来
                    
                    opts.Resources.Get<TResourceType>().AddVirtualJson(jsonPath);
                 
                 */
            });
        }

        protected override void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
        {
            context.Services.Configure<AbpVirtualFileSystemOptions>(opts =>
            {
                /**
                    ## 如何实现潜入式文件系统
                    
                    1. 将 Microsoft.Extensions.FileProviders.Embedded 包添加到包含嵌入式资源的项目（必须是直接引用，不能间接引用）
                    2. 编辑项目文件 .csproj 文件，并添加如下静态资源的路径
                       <ItemGroup>
                           <EmbeddedResource Include = "MyResources\**\*.json"/>
                           <Content Remove = "MyResources\**\*.json"/>
                       </ItemGroup>
                    3. 然后调用 AddEmbedded 把当前模块添加进来潜入式配置资源中，这样就会去扫描这些资源文件
                 */
                opts.FileSets.AddEmbedded<ThinkAbpCoreModule>();
            });
        }
    }
}
